package com.woniu.account.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.crypto.digest.MD5;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.account.dao.TGymAccountMapper;
import com.woniu.account.dto.GymAccountDto;
import com.woniu.account.dto.GymAccountRegisTryDto;
import com.woniu.account.form.GymCodeLoginForm;
import com.woniu.account.form.LoginGymAccountForm;
import com.woniu.account.form.RegistryGymAccountForm;
import com.woniu.account.model.TGymAccount;
import com.woniu.account.model.TLoginLog;
import com.woniu.account.service.TGymAccountService;
import com.woniu.core.exception.account.AccountException;
import com.woniu.core.exception.account.AccountExceptionCode;
import com.woniu.core.util.JwtUtil;
import com.woniu.core.util.RedisKeyUtil;
import com.woniu.core.util.RedisUtil;
import com.woniu.core.util.WebUtil;
import org.checkerframework.checker.units.qual.A;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static com.woniu.core.exception.account.AccountExceptionCode.LOGIN_ERROR;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 吴彦祖
 * @since 2024年04月02日
 */
@Service
public class TGymAccountServiceImpl extends ServiceImpl<TGymAccountMapper, TGymAccount> implements TGymAccountService {
    @Resource
    private TGymAccountMapper tGymAccountMapper;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private RedissonClient redissonClient;
    @Override
    public GymAccountDto findGymAccountById(Integer gymId) {

        TGymAccount tGymAccount = tGymAccountMapper.selectById(gymId);
        if(tGymAccount==null){
            throw new AccountException(AccountExceptionCode.NOT_FIND_THIS_USER);
        }
        if(tGymAccount.getAccountState()!=1){
            throw new AccountException("账号状态异常",40035);
        }
        GymAccountDto dto = BeanUtil.toBean(tGymAccount, GymAccountDto.class);
        return dto;
    }

    @Override
    public void sendRegisterCode(String phone) throws Exception {
        //判断当前手机号在1分钟内是否发送过
        if(redisUtil.exist(RedisKeyUtil.sendRegisterCodeInMinute(phone))){
            throw new Exception("一分钟内不能再次发送验证码");
        }

        //根据手机号查询用户信息
        QueryWrapper<TGymAccount> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("account_phone",phone);
        TGymAccount tGymAccount = tGymAccountMapper.selectOne(queryWrapper);
        if(tGymAccount!=null){
            throw new AccountException("手机号已被注册",400001);
        }

        //调用SMS工具发送短信验证码
//        String code = smsUtil.send(phone);
        String code = "147258";
        redisUtil.set(RedisKeyUtil.sendRegisterCodeKey(phone),code,300L);

        //保存一个1分钟过期的key
        redisUtil.set(RedisKeyUtil.sendRegisterCodeInMinute(phone),"",60L);

    }

    @Override
    public Boolean gymRegister(RegistryGymAccountForm form) throws Exception {
        String code = redisUtil.get(RedisKeyUtil.sendRegisterCodeKey(form.getAccountPhone()));
        System.out.println(code+"***********"+form.getCode());
        if(!code.equals(form.getCode())){
            throw new AccountException(AccountExceptionCode.EMAIL_CODE_ERROR);
        }
        QueryWrapper<TGymAccount> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("account_email",form.getAccountEmail());
        TGymAccount tGymAccount = tGymAccountMapper.selectOne(queryWrapper);
        if(tGymAccount!=null){
            throw new AccountException("邮箱已被注册",4000002);
        }
        TGymAccount gymAccount = BeanUtil.toBean(form, TGymAccount.class);
        String salt = form.getAccountName();
        int index = 0;
        int count = 2;
        MD5 md5 = new MD5(salt.getBytes(StandardCharsets.UTF_8),index,count);
        gymAccount.setAccountPass(md5.digestHex(form.getAccountPass()));
        gymAccount.setAccountState(1);
        gymAccount.setCreateDate(LocalDateTime.now());
        tGymAccountMapper.insert(gymAccount);
        GymAccountRegisTryDto dto = BeanUtil.toBean(gymAccount, GymAccountRegisTryDto.class);
        return true;
    }

    @Override
    public String sendLoginCode(String phone) throws Exception {
        QueryWrapper<TGymAccount> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("account_phone",phone);
        TGymAccount tGymAccount = tGymAccountMapper.selectOne(queryWrapper);
        if(tGymAccount==null){
            throw new AccountException("手机号未注册",400003);
        }
        if(redisUtil.exist(RedisKeyUtil.sendLoginCodeInMinute(phone))){
            throw new Exception("一分钟内不能再次发送验证码");
        }

//        String code = smsUtil.send(phone);
        String code = "147258";
        //将登录验证码保存到redis中
        redisUtil.set(RedisKeyUtil.sendLoginCodeKey(phone),code,300L);
        redisUtil.set(RedisKeyUtil.sendLoginCodeInMinute(phone),"",60L);
        //保存一个1分钟过期的key
        redisUtil.set(RedisKeyUtil.sendLoginCodeInMinute(phone),"",60L);
        return code;
    }

    @Override
    public GymAccountRegisTryDto codeLogin(GymCodeLoginForm form) throws Exception {
        String code = redisUtil.get(RedisKeyUtil.sendLoginCodeKey(form.getAccountPhone()));
        if(!code.equals(form.getCode())){
            throw new AccountException(AccountExceptionCode.EMAIL_CODE_ERROR);
        }

        QueryWrapper<TGymAccount> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("account_phone", form.getAccountPhone());
        TGymAccount tGymAccount = tGymAccountMapper.selectOne(queryWrapper);
        GymAccountRegisTryDto dto = BeanUtil.toBean(tGymAccount,GymAccountRegisTryDto.class);
        return dto;
    }

    @Override
    public GymAccountRegisTryDto login(LoginGymAccountForm form) {

        QueryWrapper<TGymAccount> wrapper = new QueryWrapper<>();
        //判断用户名是否存在
        wrapper.eq("account_phone",form.getAccountPhone());
        TGymAccount tGymAccount = tGymAccountMapper.selectOne(wrapper);
        if(tGymAccount==null){
            throw new AccountException(AccountExceptionCode.NOT_FIND_THIS_USER);
        }
        String salt = tGymAccount.getAccountName();
        int index = 0;
        int count = 2;
        MD5 md5 = new MD5(salt.getBytes(StandardCharsets.UTF_8),index,count);
        if(!md5.digestHex(form.getAccountPass()).equals(tGymAccount.getAccountPass())){
            throw new AccountException(AccountExceptionCode.ACCOUNTNAME_ACCOUNTPASS_ERROR);
        }
        if(tGymAccount.getAccountState()!= 1){
            throw new AccountException("账号状态异常禁止登录",40030);
        }
        GymAccountRegisTryDto dto= BeanUtil.toBean(tGymAccount,GymAccountRegisTryDto.class);
        return dto;
    }
}
